/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;

@SpringBootTest
public class IsfdSectionDataTest {

    // 维度1: 20个owner
    private static final List<String> OWNERS = Arrays.asList(
        "201781", "205679", "206701", "206703", "207333", "207354", "206152",
        "207627", "205286", "205643", "502129", "502231", "502015", "502054",
        "502123", "502282", "502285", "502281", "502090", "502320"
    );

    // 维度2: 10个sectionName
    private static final List<String> SECTION_NAMES = Arrays.asList(
        "机身交界面节点", "机头", "前机身", "中机身", "中后机身",
        "后机身", "垂尾", "平尾", "左机翼", "右机翼"
    );

    // 维度3: 8个hashUniqueKey变体
    private static final int HASH_VARIANTS = 8;

    @Test
    public void test() throws IOException {
        // 读取原始788条数据
        File inputFile = new File("D:\\要素库项目\\型材库\\100W指标\\a5238a61-1c91-4272-8515-9f0e9d061ad1.json");
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        List<Object> originalData = mapper.readValue(inputFile, List.class);

        // 生成扩展数据
        List<List<Object>> allData = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            allData.add(new ArrayList<>());
        }

        // 添加Set用于去重
        Set<String> seenKeys = Collections.newSetFromMap(new ConcurrentHashMap<>());

        int counter = 0;
        Random random = ThreadLocalRandom.current();

        for (Object original : originalData) {
            for (String owner : OWNERS) {
                for (String sectionName : SECTION_NAMES) {
                    for (int i = 0; i < HASH_VARIANTS; i++) {
                        // 克隆原始对象并修改维度字段
                        Object modified = modifyData(original, owner, sectionName, random);

                        // 检查是否已存在
                        String uniqueKey = getUniqueIdentifier(modified);
                        if (!seenKeys.add(uniqueKey)) {
                            continue; // 跳过重复数据
                        }

                        // 添加到对应的文件分组
                        allData.get(counter % 10).add(modified);
                        counter++;

                        if (counter >= 1000000) {
                            break;
                        }
                    }
                    if (counter >= 1000000) {
                        break;
                    }
                }
                if (counter >= 1000000) {
                    break;
                }
            }
            if (counter >= 1000000) {
                break;
            }
        }

        // 写入5个文件
        File outputDir = new File("D:\\要素库项目\\型材库\\100W指标\\new3");
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        for (int i = 0; i < 10; i++) {
            // 关键修改：打乱数据顺序
            Collections.shuffle(allData.get(i), random);

            File outputFile = new File(outputDir, "section_data_part_" + (i + 1) + ".json");
            mapper.writeValue(outputFile, allData.get(i));
            System.out.println("Generated file: " + outputFile.getAbsolutePath() + " with " + allData.get(i).size() + " records");
        }
    }

    private String getUniqueIdentifier(Object data) {
        try {
            Map<String, Object> map = (Map<String, Object>) data;
            return map.get("type") + "|" +
                map.get("owner") + "|" +
                map.get("sectionName") + "|" +
                map.get("serialNumber") + "|" +
                map.get("hashUniqueKey");
        } catch (Exception e) {
            return UUID.randomUUID().toString();
        }
    }

    @SuppressWarnings("unchecked")
    private Object modifyData(Object original, String owner, String sectionName, Random random) {
        Map<String, Object> data = new LinkedHashMap<>((Map<String, Object>) original);
        data.remove("_id");
        data.remove("importRecord");

        data.put("owner", owner);
        data.put("sectionName", sectionName);

        // 生成唯一hashKey
        String hashKey = generateVariantHashKey(
            data.get("type").toString(),
            owner,
            sectionName,
            random
        );
        data.put("hashUniqueKey", hashKey);

        // 独立生成serialNumber
        data.put("serialNumber", generateUniqueSerialNumber(data, random));

        // 强制差异化属性编号
        data.put("attributeNumber", String.valueOf(random.nextInt(900000) + 100000));

        adjustParametersByHashVariant(data, hashKey, random);
        return data;
    }

    private String generateUniqueSerialNumber(Map<String, Object> data, Random random) {
        String type = data.get("type").toString();
        String base = type +
            data.getOrDefault("mat1Id", "") +
            data.getOrDefault("t1LayerCode", "") +
            System.currentTimeMillis() +
            random.nextLong();

        return DigestUtils.md5Hex(base).substring(0, 16).toUpperCase();
    }

    private String generateVariantHashKey(String type, String owner, String sectionName, Random random) {
        // 使用更复杂的组合确保唯一性
        String uniqueSeed = type + owner + sectionName +
            System.currentTimeMillis() +
            random.nextLong() +
            UUID.randomUUID().toString();

        int variant = random.nextInt(8);
        return type + "-" + variant + "-" +
            UUID.nameUUIDFromBytes(uniqueSeed.getBytes()).toString().replace("-", "");
    }

    private void adjustParametersByHashVariant(java.util.Map<String, Object> data, String hashKey, Random random) {
        // 从hashKey中提取变体编号(第2部分)
        int variant = 0;
        try {
            variant = Integer.parseInt(hashKey.split("-")[1]);
        } catch (Exception e) {
            variant = random.nextInt(4); // fallback
        }

        // 通用参数调整
        String type = data.containsKey("type") && data.get("type") != null ?
            data.get("type").toString() : "UNKNOWN";
        data.put("serialNumber", type + random.nextInt(1000000));
        data.put("attributeNumber", String.valueOf(random.nextInt(900000) + 100000));

        // 根据变体编号调整参数
        switch (variant % 4) {
            case 0: // 小尺寸变体
                scaleParameters(data, 0.8 + random.nextDouble() * 0.2); // 0.8-1.0
                break;
            case 1: // 中尺寸变体
                scaleParameters(data, 1.0 + random.nextDouble() * 0.2); // 1.0-1.2
                break;
            case 2: // 大尺寸变体
                scaleParameters(data, 1.2 + random.nextDouble() * 0.3); // 1.2-1.5
                break;
            case 3: // 随机变体
                scaleParametersRandomly(data, random);
                break;
        }

        // 重新计算相关属性
        recalculateProperties(data, random);
    }

    private void scaleParameters(java.util.Map<String, Object> data, double scaleFactor) {
        // 缩放尺寸相关参数
        scaleIfPresent(data, "D", scaleFactor);
        scaleIfPresent(data, "H", scaleFactor);
        scaleIfPresent(data, "L", scaleFactor);
        scaleIfPresent(data, "W", scaleFactor);
        scaleIfPresent(data, "W1", scaleFactor);
        scaleIfPresent(data, "W2", scaleFactor);
        scaleIfPresent(data, "R", scaleFactor);
        scaleIfPresent(data, "R1", scaleFactor);
        scaleIfPresent(data, "R2", scaleFactor);
    }

    private void scaleIfPresent(java.util.Map<String, Object> data, String key, double scaleFactor) {
        if (data.containsKey(key)) {
            double value = Double.parseDouble(data.get(key).toString());
            data.put(key, value * scaleFactor);
        }
    }

    private void scaleParametersRandomly(java.util.Map<String, Object> data, Random random) {
        // 每个参数独立随机缩放
        randomScaleIfPresent(data, "D", random, 0.7, 1.5);
        randomScaleIfPresent(data, "H", random, 0.7, 1.5);
        randomScaleIfPresent(data, "L", random, 0.7, 1.5);
        randomScaleIfPresent(data, "W", random, 0.7, 1.5);
        randomScaleIfPresent(data, "W1", random, 0.7, 1.5);
        randomScaleIfPresent(data, "W2", random, 0.7, 1.5);
        randomScaleIfPresent(data, "R", random, 0.7, 1.5);
        randomScaleIfPresent(data, "R1", random, 0.7, 1.5);
        randomScaleIfPresent(data, "R2", random, 0.7, 1.5);
    }

    private void randomScaleIfPresent(java.util.Map<String, Object> data, String key, Random random, double min, double max) {
        if (data.containsKey(key)) {
            double value = Double.parseDouble(data.get(key).toString());
            double scale = min + random.nextDouble() * (max - min);
            data.put(key, value * scale);
        }
    }

    private void recalculateProperties(java.util.Map<String, Object> data, Random random) {
        // 简化版的属性重新计算
        // 实际应根据算法配置计算，这里使用随机调整模拟

        // 检查并处理A_ALL
        if (data.containsKey("A_ALL") && data.get("A_ALL") != null) {
            try {
                double baseArea = Double.parseDouble(data.get("A_ALL").toString());
                double areaScale = 0.9 + random.nextDouble() * 0.2;
                data.put("A_ALL", baseArea * areaScale);
            } catch (NumberFormatException e) {
                // 如果转换失败，保持原值或设置默认值
                data.put("A_ALL", 1.0 + random.nextDouble() * 10.0);
            }
        } else {
            data.put("A_ALL", 1.0 + random.nextDouble() * 10.0);
        }

        // 检查并处理I_ALL
        if (data.containsKey("I_ALL") && data.get("I_ALL") != null) {
            try {
                double baseIxx = Double.parseDouble(data.get("I_ALL").toString());
                double inertiaScale = 0.8 + random.nextDouble() * 0.4;
                data.put("I_ALL", baseIxx * inertiaScale);
            } catch (NumberFormatException e) {
                data.put("I_ALL", 10.0 + random.nextDouble() * 100.0);
            }
        } else {
            data.put("I_ALL", 10.0 + random.nextDouble() * 100.0);
        }

        // 检查并处理I_ADD
        if (data.containsKey("I_ADD") && data.get("I_ADD") != null) {
            try {
                double baseIyy = Double.parseDouble(data.get("I_ADD").toString());
                double inertiaScale = 0.8 + random.nextDouble() * 0.4;
                data.put("I_ADD", baseIyy * inertiaScale);
            } catch (NumberFormatException e) {
                data.put("I_ADD", 10.0 + random.nextDouble() * 100.0);
            }
        } else {
            data.put("I_ADD", 10.0 + random.nextDouble() * 100.0);
        }

        // 弹性模量小幅随机变化
        if (data.containsKey("E_E") && data.get("E_E") != null) {
            try {
                double eE = Double.parseDouble(data.get("E_E").toString());
                data.put("E_E", eE * (0.95 + random.nextDouble() * 0.1));
            } catch (NumberFormatException e) {
                data.put("E_E", 1000.0 + random.nextDouble() * 9000.0);
            }
        }

        if (data.containsKey("E_G") && data.get("E_G") != null) {
            try {
                double eG = Double.parseDouble(data.get("E_G").toString());
                data.put("E_G", eG * (0.95 + random.nextDouble() * 0.1));
            } catch (NumberFormatException e) {
                data.put("E_G", 1000.0 + random.nextDouble() * 9000.0);
            }
        }
    }
}
